import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom, timeout, retry } from 'rxjs';
import { AxiosResponse, AxiosError } from 'axios';
import { v4 as uuidv4 } from 'uuid';
import { 
  ApiProvider, 
  TargetProvider, 
  ForwardingContext, 
  ForwardingResult, 
  GenericRequest, 
  GenericResponse 
} from '../interfaces/api-adapter.interface';
import { AdapterRegistryService } from './adapter-registry.service';

/**
 * 通用转发服务
 * 支持任意 AI API 到任意目标 API 的转发
 */
@Injectable()
export class GenericForwardingService {
  private readonly logger = new Logger(GenericForwardingService.name);

  constructor(
    private readonly httpService: HttpService,
    private readonly adapterRegistry: AdapterRegistryService
  ) {}

  /**
   * 转发请求到指定的目标 API
   */
  async forwardRequest(
    provider: ApiProvider,
    target: TargetProvider,
    originalRequest: any,
    userInfo: any,
    config?: any
  ): Promise<ForwardingResult> {
    const context: ForwardingContext = {
      requestId: uuidv4(),
      provider,
      target,
      originalRequest,
      userInfo,
      config: config || {},
      startTime: Date.now()
    };

    this.logger.log(`Starting forwarding: ${provider} -> ${target}`, {
      requestId: context.requestId,
      userAgent: userInfo?.userAgent,
      ip: userInfo?.ip
    });

    try {
      // 1. 获取适配器
      const adapter = this.adapterRegistry.getAdapter(provider, target);
      if (!adapter) {
        throw new Error(`No adapter found for ${provider} -> ${target}`);
      }

      // 2. 验证原始请求
      const isValid = await adapter.validateRequest(originalRequest);
      if (!isValid) {
        throw new Error(`Invalid request format for ${provider} API`);
      }

      // 3. 转换为通用格式
      const genericRequest = await adapter.convertToGeneric(originalRequest);
      
      // 4. 转换为目标格式
      const targetRequest = await adapter.convertFromGeneric(genericRequest);
      
      // 5. 发送到目标 API
      const targetResponse = await this.sendToTargetApi(adapter, targetRequest, context);
      
      // 6. 解析目标响应
      const genericResponse = await adapter.parseTargetResponse(targetResponse, originalRequest);
      
      // 7. 转换为源 API 格式
      const sourceResponse = await adapter.convertToSourceResponse(genericResponse, originalRequest);

      const result: ForwardingResult = {
        success: true,
        response: sourceResponse,
        context,
        endTime: Date.now(),
        duration: Date.now() - context.startTime,
        metadata: {
          genericRequest: this.sanitizeForLogging(genericRequest),
          genericResponse: this.sanitizeForLogging(genericResponse)
        }
      };

      this.logger.log(`Forwarding completed successfully`, {
        requestId: context.requestId,
        duration: result.duration,
        provider,
        target
      });

      return result;

    } catch (error) {
      const result: ForwardingResult = {
        success: false,
        error: error instanceof Error ? error : new Error(String(error)),
        context,
        endTime: Date.now(),
        duration: Date.now() - context.startTime
      };

      this.logger.error(`Forwarding failed: ${error.message}`, {
        requestId: context.requestId,
        duration: result.duration,
        provider,
        target,
        error: error.stack
      });

      return result;
    }
  }

  /**
   * 发送请求到目标 API
   */
  private async sendToTargetApi(adapter: any, targetRequest: any, context: ForwardingContext): Promise<any> {
    const endpoint = adapter.getTargetEndpoint('chat/completions');
    const headers = await adapter.getRequestHeaders(context.config);
    
    // 构建完整的 URL
    const url = endpoint.startsWith('http') ? endpoint : `${context.config.baseUrl || ''}${endpoint}`;
    
    this.logger.debug(`Sending request to target API`, { 
      url, 
      requestId: context.requestId,
      headers: this.maskSensitiveHeaders(headers)
    });

    try {
      const response: AxiosResponse = await firstValueFrom(
        this.httpService.post(url, targetRequest, {
          headers,
          timeout: context.config.timeout || 30000,
          validateStatus: (status) => status < 500
        }).pipe(
          timeout({ each: context.config.timeout || 30000 }),
          retry({
            count: context.config.retryAttempts || 3,
            delay: (error, retryCount) => {
              this.logger.warn(`Request failed, retrying (${retryCount}/${context.config.retryAttempts || 3}): ${error.message}`);
              const delayTime = 1000 * Math.pow(2, retryCount - 1);
              return new Promise(resolve => setTimeout(resolve, delayTime));
            }
          })
        )
      );

      // 处理非 200 状态码
      if (response.status >= 400) {
        throw new HttpException(
          {
            type: 'error',
            error: {
              type: this.mapHttpStatusToErrorType(response.status),
              message: response.data?.error?.message || `Target API returned status ${response.status}`
            }
          },
          response.status
        );
      }

      return response.data;

    } catch (error) {
      if (error instanceof AxiosError) {
        this.logger.error('Target API Error', {
          status: error.response?.status,
          statusText: error.response?.statusText,
          data: error.response?.data,
          message: error.message,
          requestId: context.requestId
        });
        
        throw new HttpException(
          {
            type: 'error',
            error: {
              type: this.mapHttpStatusToErrorType(error.response?.status || 500),
              message: error.response?.data?.error?.message || error.message
            }
          },
          error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR
        );
      }
      
      throw error;
    }
  }

  /**
   * 批量转发请求（用于批处理场景）
   */
  async forwardBatch(
    provider: ApiProvider,
    target: TargetProvider,
    requests: any[],
    userInfo: any,
    config?: any
  ): Promise<ForwardingResult[]> {
    this.logger.log(`Starting batch forwarding: ${requests.length} requests`, {
      provider,
      target
    });

    const results = await Promise.allSettled(
      requests.map(request => this.forwardRequest(provider, target, request, userInfo, config))
    );

    return results.map(result => {
      if (result.status === 'fulfilled') {
        return result.value;
      } else {
        return {
          success: false,
          error: new Error(result.reason),
          context: {
            requestId: uuidv4(),
            provider,
            target,
            originalRequest: null,
            userInfo,
            config: config || {},
            startTime: Date.now()
          },
          endTime: Date.now(),
          duration: 0
        };
      }
    });
  }

  /**
   * 获取支持的转发路径
   */
  getSupportedRoutes(): Array<{ provider: ApiProvider; target: TargetProvider }> {
    return this.adapterRegistry.getSupportedRoutes();
  }

  /**
   * 检查转发服务健康状态
   */
  async checkHealth(): Promise<{
    status: 'healthy' | 'degraded' | 'unhealthy';
    adapters: Map<string, any>;
    supportedRoutes: number;
    lastCheck: Date;
  }> {
    const adapterHealth = await this.adapterRegistry.checkAllAdaptersHealth();
    const supportedRoutes = this.getSupportedRoutes();
    
    // 判断整体健康状态
    const healthyAdapters = Array.from(adapterHealth.values()).filter(h => h.status === 'healthy');
    const totalAdapters = adapterHealth.size;
    
    let overallStatus: 'healthy' | 'degraded' | 'unhealthy';
    if (healthyAdapters.length === totalAdapters && totalAdapters > 0) {
      overallStatus = 'healthy';
    } else if (healthyAdapters.length > 0) {
      overallStatus = 'degraded';
    } else {
      overallStatus = 'unhealthy';
    }

    return {
      status: overallStatus,
      adapters: adapterHealth,
      supportedRoutes: supportedRoutes.length,
      lastCheck: new Date()
    };
  }

  /**
   * 映射 HTTP 状态码到错误类型
   */
  private mapHttpStatusToErrorType(status: number): string {
    switch (Math.floor(status / 100)) {
      case 4:
        if (status === 401) return 'authentication_error';
        if (status === 403) return 'permission_error';
        if (status === 404) return 'not_found_error';
        if (status === 429) return 'rate_limit_error';
        return 'invalid_request_error';
      case 5:
        return 'api_error';
      default:
        return 'api_error';
    }
  }

  /**
   * 掩码敏感头部信息
   */
  private maskSensitiveHeaders(headers: Record<string, string>): Record<string, string> {
    const masked = { ...headers };
    
    if (masked.authorization) {
      const auth = masked.authorization;
      if (auth.length > 20) {
        masked.authorization = auth.substring(0, 10) + '***' + auth.substring(auth.length - 4);
      } else {
        masked.authorization = '***';
      }
    }

    return masked;
  }

  /**
   * 清理日志数据，移除敏感信息
   */
  private sanitizeForLogging(data: any): any {
    if (!data) return data;
    
    const sanitized = JSON.parse(JSON.stringify(data));
    
    // 递归清理敏感字段
    const sensitiveFields = ['token', 'authorization', 'password', 'secret', 'key'];
    
    function cleanObject(obj: any): any {
      if (typeof obj !== 'object' || obj === null) return obj;
      
      for (const [key, value] of Object.entries(obj)) {
        if (sensitiveFields.some(field => key.toLowerCase().includes(field))) {
          obj[key] = '***';
        } else if (typeof value === 'object') {
          obj[key] = cleanObject(value);
        }
      }
      
      return obj;
    }
    
    return cleanObject(sanitized);
  }
}